import { reactive } from 'vue'
import { webSocketService } from './websocket-service'
import type { UnifiedTaskMessage } from './websocket-service'

/**
 * 任务状态
 */
export enum TaskStatus {
  PENDING = 'PENDING',
  STARTED = 'STARTED',
  PROCESSING = 'PROCESSING',
  COMPLETED = 'COMPLETED',
  FAILED = 'FAILED',
  CANCELLED = 'CANCELLED'
}

/**
 * 任务信息
 */
export interface TaskInfo {
  id: string           // 任务ID
  type: string         // 任务类型
  status: TaskStatus   // 任务状态
  progress: number     // 任务进度
  message: string      // 任务消息
  startTime?: Date     // 开始时间
  endTime?: Date       // 结束时间
  params?: any         // 任务参数
  result?: any         // 任务结果
}

/**
 * 任务状态管理服务
 */
class TaskStateManager {
  // 当前正在执行的任务
  private runningTasks = reactive<Map<string, TaskInfo>>(new Map())
  
  // 任务历史记录
  private taskHistory = reactive<Map<string, TaskInfo>>(new Map())
  
  // 是否正在处理某个任务
  private isTaskRunning = reactive<Map<string, boolean>>(new Map())
  
  constructor() {
    // 订阅统一任务消息
    this.subscribeToTaskMessages()
  }
  
  /**
   * 检查任务是否正在运行
   * @param taskId 任务ID
   * @returns 是否正在运行
   */
  isRunning(taskId: string): boolean {
    return this.isTaskRunning.get(taskId) || false
  }
  
  /**
   * 获取正在运行的任务信息
   * @param taskId 任务ID
   * @returns 任务信息
   */
  getRunningTask(taskId: string): TaskInfo | undefined {
    return this.runningTasks.get(taskId)
  }
  
  /**
   * 获取所有正在运行的任务
   * @returns 正在运行的任务列表
   */
  getAllRunningTasks(): TaskInfo[] {
    return Array.from(this.runningTasks.values())
  }
  
  /**
   * 获取任务历史记录
   * @param taskId 任务ID
   * @returns 任务历史信息
   */
  getTaskHistory(taskId: string): TaskInfo | undefined {
    return this.taskHistory.get(taskId)
  }
  
  /**
   * 获取所有任务历史记录
   * @returns 任务历史记录列表
   */
  getAllTaskHistory(): TaskInfo[] {
    return Array.from(this.taskHistory.values())
  }
  
  /**
   * 开始任务（防重复提交）
   * @param taskId 任务ID
   * @param type 任务类型
   * @param params 任务参数
   * @returns 是否成功开始任务
   */
  startTask(taskId: string, type: string, params?: any): boolean {
    // 检查任务是否已在运行
    if (this.isRunning(taskId)) {
      console.warn(`任务 ${taskId} 已在运行中，跳过重复提交`)
      return false
    }
    
    // 创建任务信息
    const taskInfo: TaskInfo = {
      id: taskId,
      type,
      status: TaskStatus.STARTED,
      progress: 0,
      message: '任务已开始',
      startTime: new Date(),
      params
    }
    
    // 添加到运行任务列表
    this.runningTasks.set(taskId, taskInfo)
    this.isTaskRunning.set(taskId, true)
    
    console.log(`任务 ${taskId} 已开始`)
    return true
  }
  
  /**
   * 更新任务状态
   * @param taskId 任务ID
   * @param status 任务状态
   * @param progress 任务进度
   * @param message 任务消息
   */
  updateTaskStatus(taskId: string, status: TaskStatus, progress?: number, message?: string): void {
    const task = this.runningTasks.get(taskId)
    if (!task) {
      console.warn(`未找到正在运行的任务 ${taskId}`)
      return
    }
    
    // 更新任务信息
    task.status = status
    if (progress !== undefined) {
      task.progress = progress
    }
    if (message !== undefined) {
      task.message = message
    }
    
    // 如果任务完成或失败，移动到历史记录
    if (status === TaskStatus.COMPLETED || status === TaskStatus.FAILED || status === TaskStatus.CANCELLED) {
      task.endTime = new Date()
      this.taskHistory.set(taskId, { ...task })
      this.runningTasks.delete(taskId)
      this.isTaskRunning.set(taskId, false)
      
      console.log(`任务 ${taskId} 已${status === TaskStatus.COMPLETED ? '完成' : status === TaskStatus.FAILED ? '失败' : '取消'}`)
    }
  }
  
  /**
   * 取消任务
   * @param taskId 任务ID
   * @returns 是否成功取消
   */
  cancelTask(taskId: string): boolean {
    if (!this.isRunning(taskId)) {
      return false
    }
    
    this.updateTaskStatus(taskId, TaskStatus.CANCELLED, undefined, '任务已取消')
    return true
  }
  
  /**
   * 清理任务历史记录
   * @param maxHistory 最大历史记录数
   */
  cleanHistory(maxHistory: number = 100): void {
    if (this.taskHistory.size <= maxHistory) {
      return
    }
    
    // 按结束时间排序，保留最新的记录
    const sortedTasks = Array.from(this.taskHistory.entries())
      .sort((a, b) => {
        const aTime = a[1].endTime?.getTime() || 0
        const bTime = b[1].endTime?.getTime() || 0
        return bTime - aTime
      })
    
    // 清理超出限制的记录
    this.taskHistory.clear()
    sortedTasks.slice(0, maxHistory).forEach(([id, task]) => {
      this.taskHistory.set(id, task)
    })
  }
  
  /**
   * 订阅任务消息
   */
  private subscribeToTaskMessages(): void {
    // 连接WebSocket并订阅统一任务主题
    webSocketService.connect().then(() => {
      // 订阅所有任务消息
      webSocketService.subscribeToUnifiedTask((message: UnifiedTaskMessage) => {
        this.handleTaskMessage(message)
      })
    }).catch(error => {
      console.error('连接WebSocket失败，任务状态更新将不可用:', error)
      // WebSocket连接失败不影响任务管理功能，只是无法实时更新状态
    })
  }
  
  /**
   * 处理任务消息
   * @param message 任务消息
   */
  private handleTaskMessage(message: UnifiedTaskMessage): void {
    const { taskId, status, progress, message: msg } = message
    
    // 如果任务不在运行列表中，添加到运行列表
    if (!this.runningTasks.has(taskId) && 
        (status === TaskStatus.STARTED || status === TaskStatus.PROCESSING)) {
      this.runningTasks.set(taskId, {
        id: taskId,
        type: message.type,
        status: status as TaskStatus,
        progress: progress || 0,
        message: msg || '',
        startTime: new Date()
      })
      this.isTaskRunning.set(taskId, true)
    }
    
    // 更新任务状态
    if (this.runningTasks.has(taskId)) {
      this.updateTaskStatus(taskId, status as TaskStatus, progress, msg)
    }
  }
}

// 导出单例实例
export const taskStateManager = new TaskStateManager()

// 导出便捷的组合式API
export function useTaskManager() {
  return {
    isRunning: (taskId: string) => taskStateManager.isRunning(taskId),
    getRunningTask: (taskId: string) => taskStateManager.getRunningTask(taskId),
    getAllRunningTasks: () => taskStateManager.getAllRunningTasks(),
    getTaskHistory: (taskId: string) => taskStateManager.getTaskHistory(taskId),
    getAllTaskHistory: () => taskStateManager.getAllTaskHistory(),
    startTask: (taskId: string, type: string, params?: any) => taskStateManager.startTask(taskId, type, params),
    cancelTask: (taskId: string) => taskStateManager.cancelTask(taskId),
    cleanHistory: (maxHistory?: number) => taskStateManager.cleanHistory(maxHistory)
  }
}